package com.quectel.dms.controller.simulation;

import cn.hutool.core.lang.func.LambdaUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.quectel.business.dms.AccessorUtils;
import com.quectel.business.dms.application.access.accessor.ipg.AbstractIntelligentParkingGateAccessor;
import com.quectel.constant.core.car.CarConstants;
import com.quectel.constant.core.eventrecord.CarAccessRecordConstants;
import com.quectel.constant.core.parkingcard.ParkingCardMemberDeviceConstants;
import com.quectel.core.module.application.service.ApplicationService;
import com.quectel.core.module.device.dto.DeviceDto;
import com.quectel.core.module.device.service.DeviceService;
import com.quectel.core.module.parkingcard.dto.ParkingCardMemberDeviceDto;
import com.quectel.core.module.parkingcard.dto.ParkingCardMemberDto;
import com.quectel.core.module.parkingcard.dto.ParkingCardOrderDeviceDto;
import com.quectel.core.module.parkingcard.service.ParkingCardMemberDeviceService;
import com.quectel.core.module.parkingcard.service.ParkingCardMemberService;
import com.quectel.core.module.parkingcard.service.ParkingCardOrderDeviceService;
import com.quectel.dms.controller.BaseController;
import com.quectel.sdk.simulation.parkinggate.model.AuthCarResp;
import com.quectel.sys.module.sys.dto.SysTenantDto;
import com.quectel.sys.module.sys.service.SysTenantService;
import com.quectel.util.common.DateUtils;
import com.quectel.util.common.JacksonUtils;
import com.quectel.util.common.Response;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collections;
import java.util.Objects;

/**
 * 在这里编写说明
 *
 * @author: rananxin
 * @email: ryan.ran@quectel.com
 * @date: 2022-12-13 14:35:00
 */
@RestController
@RequestMapping("simulation")
@Tag(name = "SimulationCollectController")
public class SimulationCollectController extends BaseController {

    @DubboReference
    private DeviceService deviceService;
    @DubboReference
    private ApplicationService applicationService;
    @DubboReference
    private ParkingCardMemberDeviceService parkingCardMemberDeviceService;
    @DubboReference
    private SysTenantService sysTenantService;
    @DubboReference
    private ParkingCardMemberService parkingCardMemberService;
    @DubboReference
    private ParkingCardOrderDeviceService parkingCardOrderDeviceService;


    private static final Logger LOGGER = LoggerFactory.getLogger(SimulationCollectController.class);

    @PostMapping("eventRcv/authResp/{tenantCode}")
    public Response<Object> authResp(@RequestBody @Validated AuthCarResp authCarResp, @PathVariable String tenantCode) {
        SysTenantDto sysTenantDto = sysTenantService.selectOneByCode(tenantCode);
        if (Objects.isNull(sysTenantDto)) {
            return Response.error("租户不存在");
        }

        for (AuthCarResp.ResultInfoCls resultInfoCls : authCarResp.getResultInfo()) {
            DeviceDto deviceDto = deviceService.selectByUniqueId(resultInfoCls.getCode(), sysTenantDto.getId());
            if (Objects.isNull(deviceDto)) {
                continue;
            }
            ParkingCardMemberDto memberDto = parkingCardMemberService.selectOneMember(deviceDto.getVillageId(), authCarResp.getLicense(), authCarResp.getLicenseColor());
            if (Objects.isNull(memberDto)) {
                continue;
            }
            ParkingCardMemberDeviceDto newlyMemberDeviceDto = new ParkingCardMemberDeviceDto();
            newlyMemberDeviceDto.setDeviceId(deviceDto.getId());
            newlyMemberDeviceDto.setParkingCardMemberId(memberDto.getId());
            newlyMemberDeviceDto.setAuthType(authCarResp.getType());
            newlyMemberDeviceDto.setStatus(Boolean.TRUE.equals(resultInfoCls.getIsSuccess())
                    ? ParkingCardMemberDeviceConstants.StatusEnum.SUCCESS.getStatus()
                    : ParkingCardMemberDeviceConstants.StatusEnum.FAILURE.getStatus());
            parkingCardMemberDeviceService.updateByUk(newlyMemberDeviceDto);

            if (authCarResp.getPayload().containsKey(LambdaUtil.getFieldName(ParkingCardOrderDeviceDto::getParkingCardOrderId))) {
                Object o = authCarResp.getPayload().get(LambdaUtil.getFieldName(ParkingCardOrderDeviceDto::getParkingCardOrderId));
                ParkingCardOrderDeviceDto newlyOrderDeviceDto = new ParkingCardOrderDeviceDto();
                newlyOrderDeviceDto.setDeviceId(deviceDto.getId());
                newlyOrderDeviceDto.setParkingCardOrderId(Long.valueOf(o + ""));
                newlyOrderDeviceDto.setStatus(Boolean.TRUE.equals(resultInfoCls.getIsSuccess())
                        ? ParkingCardMemberDeviceConstants.StatusEnum.SUCCESS.getStatus()
                        : ParkingCardMemberDeviceConstants.StatusEnum.FAILURE.getStatus());
                parkingCardOrderDeviceService.updateByUk(newlyOrderDeviceDto);
            }
        }
        return Response.ok();
    }

    public static void main(String[] args) {
        BigDecimal b21 = new BigDecimal("21");
        BigDecimal b5 = new BigDecimal("5");

        BigDecimal divide = b21.divide(b5, 0, RoundingMode.UP);
        System.out.println(divide.toPlainString());
    }

    @PostMapping("eventRcv/parkingGateAccess/{tenantCode}")
    public Response<Object> access(@RequestBody String data, @PathVariable String tenantCode) {
        LOGGER.info("模拟平台 订阅事件回调  data {} 时间 {}", data, DateUtils.getCurrentDateStr(DateUtils.FormatType.COMMON));

        SysTenantDto sysTenantDto = sysTenantService.selectOneByCode(tenantCode);
        if (Objects.isNull(sysTenantDto)) {
            return Response.error("租户不存在");
        }

        JsonNode parse = JacksonUtils.parse(data);
        String deviceCode = parse.get("deviceCode").asText();
        String license = parse.get("license").asText();
        String eventTime = parse.get("eventTime").asText();
        int inOrOut = parse.get("inOrOut").asInt();
        byte type = (byte) parse.get("type").asInt();
        String img = Objects.nonNull(parse.get("img")) ? parse.get("img").asText() : null;

        DeviceDto deviceDto = deviceService.selectByUniqueId(deviceCode, sysTenantDto.getId());
        AbstractIntelligentParkingGateAccessor intelligentParkingGateAccessor = AccessorUtils.getIntelligentParkingGateAccessor(deviceDto.getDeviceType());
        assert intelligentParkingGateAccessor != null;

        AbstractIntelligentParkingGateAccessor.HandleReq handleReq = new AbstractIntelligentParkingGateAccessor
                .HandleReq(deviceDto, CarConstants.LicenseColorEnum.COMMON, license, inOrOut == 1 ? CarAccessRecordConstants.InOrOutEnum.IN
                : CarAccessRecordConstants.InOrOutEnum.OUT, Objects.requireNonNull(DateUtils.parse(eventTime, DateUtils.FormatType.COMMON)));
        handleReq.setSnapImages(JacksonUtils.toJsonString(Collections.singletonList(img)));

        if (new Byte((byte) 1).equals(type) || new Byte((byte) 3).equals(type)) {
            // 进或出
            intelligentParkingGateAccessor.accessHandle(handleReq);
        } else if (new Byte((byte) 2).equals(type)) {
            intelligentParkingGateAccessor.crimping(handleReq);
        }

        return Response.ok();
    }

}
